package com.cxq;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Created by cxq on 2020/7/26.
 */
/*
*
* 读写锁：
*   可以同时读；
*   读的时候不能写；
*   不可以同时写；
*   写的时候不能读；
*/
public class ReadWriteLockDemo {

    private Map<String,String> map = new HashMap<String, String>();//读写对象
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();//读操作锁
    private ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();//写操作锁

    public String get(String key){
        String name = Thread.currentThread().getName();
        readLock.lock();
        try{
            System.out.println(name+":读操作已加锁，开始读操作...");
            Thread.sleep(1000);
            return map.get(key);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }finally {
            readLock.unlock();
            System.out.println(name+":读操作已解锁，读操作结束");
        }
    }

    public void put(String key,String value){
        String name = Thread.currentThread().getName();
        writeLock.lock();
        try {
            System.out.println(name+":写操作已加锁，开始写操作...");
            map.put(key,value);
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            writeLock.unlock();
            System.out.println(name+":写操作已解锁，写操作结束");
        }
    }

    public static void main(String[] args) {
        final ReadWriteLockDemo readWriteLockDemo = new ReadWriteLockDemo();
//        readWriteLockDemo.put("key1","value1");
//        readWriteLockDemo.put("key2","value2");
//        readWriteLockDemo.put("key3","value3");

        new Thread("写线程1"){
            public void run(){
                readWriteLockDemo.put("key1","value1");
            }
        }.start();
        new Thread("写线程2"){
            public void run(){
                readWriteLockDemo.put("key2","value2");
            }
        }.start();
        new Thread("写线程3"){
            public void run(){
                readWriteLockDemo.put("key3","value3");
            }
        }.start();



        new Thread("读线程1"){
            public void run(){
                System.out.println(readWriteLockDemo.get("key1"));
            }
        }.start();
        new Thread("读线程2"){
            public void run(){
                System.out.println(readWriteLockDemo.get("key2"));
            }
        }.start();
        new Thread("读线程3"){
            public void run(){
                System.out.println(readWriteLockDemo.get("key3"));
            }
        }.start();
    }

}
